9558. Флаги

 

Флаг состоит из n вертикальных полос, каждая из которых может быть окрашена в белый, красный или синий цвет. При этом:

·        Никакие две соседние полосы не имеют одинаковый цвет.

·        Любая синяя полоса обязательно должна находиться между красной и белой полосами (в любом порядке).

Сколько существует способов раскрасить флаг из n полос?

 

Вход. Одно целое число n (1 ≤ n ≤ 106) – количество полос на флаге.

 

Выход. Выведите количество способов раскрасить флаг из n полос. Ответ необходимо вывести по модулю 109 + 7.

 

Пример входа

Пример выхода

3

4

 

 

РЕШЕНИЕ

числа Фибоначчи

 

Анализ алгоритма

Пусть:

·        fr(n) – количество способов раскрасить флаг из n полос, начав с красной полосы;

·        fw(n) – количество способов раскрасить флаг из n полос, начав с белой полосы;

 

Рассмотрим вычисление функции fr(n):

·        Если следующей за красной поставить белую полосу, то оставшийся флаг длины n – 1 можно раскрасить fw(n – 1) способами;

·        Если следующей за красной поставить синюю полосу, то за синей должна стоять белая полоса. После чего оставшийся флаг длины n – 2 можно раскрасить fw(n – 2) способами;

Итак, имеем равенство:

fr(n) = fw(n – 1) + fw(n – 2)

Аналогичными рассуждениями получаем:

fw(n) = fr(n – 1) + fr(n – 2)

Начальные условия для первой рекуррентности очевидны:

·        fr(1) = 1: Флаг из одной полосы, начинающийся с красной, может быть раскрашен только одним способом – R.

·        fr(2) = 1: Если первая полоса красная, то вторая не может быть красной и не может быть синей (синяя должна находиться между красной и белой), следовательно, вторая полоса обязана быть белой. Единственный вариант – RW.

Аналогично

fw(1) = 1, fw(2) = 1

Обе функции – и fr(n) и fw(n) задают числа Фибоначчи:

fr(n) = Fn,

fw(n) = Fn

Раскрашивание флага начинается с первой полосы. Она может быть либо красной, либо белой. Следовательно, общее количество способов раскрасить флаг равно

fr(n) + fw(n) = 2 * Fn

 

Реализация алгоритма

Объявим константы.

 

#define MAX 1000001

#define MOD 1000000007

 

Объявим массив fib для хранения чисел Фибоначчи.

 

long long fib[MAX];

 

Читаем входное значение n.

 

scanf("%d", &n);

 

Заполняем массив fib числами Фибоначчи.

 

fib[1] = 1; fib[2] = 1;

for (i = 3; i < MAX; i++)

  fib[i] = (fib[i - 1] + fib[i - 2]) % MOD;

 

Выводим ответ.

 

printf("%lld\n", (2 * fib[n]) % MOD);